#include "dma.h"

uint8_t rxbuffer[64];

void usart0rx_dmainit(void)
{
    dma_parameter_struct dma_init_struct;
    rcu_periph_clock_enable(RCU_DMA0);
    /* user manual P213,In the DMA0 request mapping table, USART0_RX corresponds to Channel4 */
    /* deinitialize DMA channel4 (USART0 rx) */
    dma_deinit(DMA0, DMA_CH4);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)rxbuffer;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = 64;
    dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART0);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH4, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH4);
    dma_memory_to_memory_disable(DMA0, DMA_CH4);
    /* enable DMA channel4 */
    dma_channel_enable(DMA0, DMA_CH4);
}

void usart0tx_dmainit(void)
{
    dma_parameter_struct dma_init_struct;
    rcu_periph_clock_enable(RCU_DMA0);
    /*user manual P213,In the DMA0 request mapping table, USART0_TX corresponds to Channel3 */
    /* deinitialize DMA channel3 (USART0 Tx) */
    dma_deinit(DMA0, DMA_CH3);
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_addr = 0;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = 0;
    dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART0);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH3, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH3);
    dma_memory_to_memory_disable(DMA0, DMA_CH3);
    /* disable DMA channel3 */
    dma_channel_disable(DMA0, DMA_CH3);
    /* enable USART DMA for transmission */
    usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
}

void usart0_dma_send(uint8_t *buffer, uint32_t length)
{
    dma_memory_address_config(DMA0, DMA_CH3, (uint32_t)(buffer));
    dma_transfer_number_config(DMA0, DMA_CH3, length);
    dma_channel_enable(DMA0, DMA_CH3);
    while(dma_flag_get(DMA0, DMA_CH3, DMA_INTF_FTFIF) == RESET );
    dma_flag_clear(DMA0, DMA_CH3, DMA_FLAG_FTF);
    dma_channel_disable(DMA0, DMA_CH3);
}
